home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / local / sbin / live-persist < prev    next >
Encoding:
Text File  |  2013-01-09  |  8.4 KB  |  369 lines

  1. #!/bin/bash
  2.  
  3. # import Cmdline()
  4. . /lib/live/boot/cmdline.sh
  5.  
  6. # Set variable name that's needed by get_custom_mounts(),
  7. # and now initialized by live-boot in a file that we certainly
  8. # don't want to source.
  9. export persistence_list="live-persistence.conf"
  10.  
  11. # This will import the following functions and variables used below:
  12. #   activate_custom_mounts()
  13. #   get_custom_mounts()
  14. #   open_luks_device()
  15. #   probe_for_gpt_name()
  16. #   removable_dev()
  17. #   removable_usb_dev()
  18. #   storage_devices()
  19. #   where_is_mounted()
  20. #   $custom_overlay_label
  21. . /lib/live/boot/misc-helpers.sh
  22.  
  23. usage ()
  24. {
  25.     local cmd=${0##*/}
  26.     echo "Usage: ${cmd} [OPTION]... list [LABEL]...
  27. List (on stdout) all GPT partitions with names among LABEL(s) that are
  28. compatible with live-boot's overlay persistence, and that are adhering to
  29. live-boot's persistence filters (e.g. persistent-media). If no LABEL is given
  30. the default in live-boot is used ('${custom_overlay_label}').
  31.    or: ${cmd} [OPTION]... activate VOLUME...
  32. Activates persistence on the given VOLUME(s). Successes and failures are
  33. written to stdout. There are no checks for whether the given volumes adhere
  34. to live-boot's options.
  35.  
  36. Kernel command-line options are parsed just like in live-boot and have the same
  37. effect (see live-boot(7) for more information)
  38.  
  39. Arguments to options must be passed using an equality sign. LISTs are coma
  40. separated. Most options correspond to the persistent-* options of live-boot,
  41. and will override the corresponging options parsed from the kernel command-line.
  42.  
  43. General options:
  44.   --help                display this help and exit
  45.   --log-file=FILE       log the bash execution trace to FILE
  46.  
  47. Options affecting the 'list' action:
  48.   --encryption=LIST     override 'persistent-encryption'
  49.   --media=VALUE         override 'persistent-media'
  50.  
  51. Options affecting the 'activate' action:
  52.   --read-only           enable 'persistent-read-only'
  53.   --read-write          disable 'persistent-read-only'
  54.   --union=VALUE         override 'union'
  55. "
  56. }
  57.  
  58. warning ()
  59. {
  60.     echo "warning: ${@}" >&2
  61. }
  62.  
  63. error ()
  64. {
  65.     echo "error: ${@}" >&2
  66.     exit 1
  67. }
  68.  
  69. dbus_udisks_get_attribute ()
  70. {
  71.     local dev="${1}"
  72.     local attribute="${2}"
  73.     local re='^[[:space:]]*variant[[:space:]]\+string[[:space:]]\+"\(.*\)"$'
  74.     dbus-send --system --print-reply --dest=org.freedesktop.UDisks \
  75.         /org/freedesktop/UDisks/devices/$(basename ${dev}) \
  76.         org.freedesktop.DBus.Properties.Get \
  77.         string:org.freedesktop.UDisks.Device \
  78.         string:"${attribute}" 2>/dev/null | \
  79.         grep -e "${re}" | sed "s|${re}|\1|"
  80. }
  81.  
  82. # We override the following two functions from live-helpers since old
  83. # blkid (i.e. util-linux and libblkid1) doesn't support GPT. We use dbus
  84. # instead (which should be available in user-space).
  85. get_gpt_name ()
  86. {
  87.     local dev="${1}"
  88.     dbus_udisks_get_attribute ${dev} partition-label
  89. }
  90.  
  91. is_gpt_device ()
  92. {
  93.     local dev="${1}"
  94.     [ "$(dbus_udisks_get_attribute ${dev} partition-scheme)" = "gpt" ]
  95. }
  96.  
  97.  
  98. # We override live-boot's logging facilities to get more useful error messages
  99. log_warning_msg ()
  100. {
  101.     warning ${@}
  102. }
  103.  
  104. # We override live-boot's panic() since it does a lot of crazy stuff
  105. panic ()
  106. {
  107.     error ${@}
  108. }
  109.  
  110. # Fix persistent ~/.gconf sub-dirs; activate_custom_mounts() creates
  111. # empty dirs up to its mountpoint, but the file %gconf.xml has to be
  112. # present in each of ~/.gconf's subdirs to make them valid. Hence we
  113. # have a problem with a persistent ~/.gconf/X/Y if ~/.gconf/X was
  114. # created by activate_custom_mounts() since it would lack its
  115. # %gconf.xml file, making ~/.gconf/X/Y invalid. This functions makes
  116. # sure that all subdirs of ~/.gconf contain %gconf.xml.
  117. fix_gconf_dirs ()
  118. {
  119.     for home in /home/*
  120.     do
  121.         if [ ! -e "${home}/.gconf" ]
  122.         then
  123.             continue
  124.         fi
  125.         local ownership=$(stat -c "%u:%g" "${home}")
  126.         find "${home}/.gconf" -type d | while IFS="" read -r dir
  127.         do
  128.             local conf="${dir}/%gconf.xml"
  129.             if [ ! -e "${conf}" ]; then
  130.                 touch "${conf}"
  131.                 chown ${ownership} "${conf}"
  132.             fi
  133.         done
  134.     done
  135. }
  136.  
  137. list_gpt_volumes ()
  138. {
  139.     local labels=${@}
  140.  
  141.     local whitelistdev=""
  142.     case "${PERSISTENCE_MEDIA}" in
  143.         removable)
  144.             whitelistdev="$(removable_dev)"
  145.             [ -z "${whitelistdev}" ] && return
  146.             ;;
  147.         removable-usb)
  148.             whitelistdev="$(removable_usb_dev)"
  149.             [ -z "${whitelistdev}" ] && return
  150.             ;;
  151.         *)
  152.             if grep -qs -w -E '(live-media|bootfrom)=removable-usb' /proc/cmdline ; then
  153.                 whitelistdev="$(removable_usb_dev)"
  154.                 [ -z "${whitelistdev}" ] && return
  155.             elif grep -qs -w -E '(live-media|bootfrom)=removable' /proc/cmdline ; then
  156.                 whitelistdev="$(removable_dev)"
  157.                 [ -z "${whitelistdev}" ] && return
  158.             else
  159.                 whitelistdev=""
  160.             fi
  161.             ;;
  162.     esac
  163.  
  164.     for dev in $(storage_devices "" "${whitelistdev}")
  165.     do
  166.         if ( is_luks_partition ${dev} >/dev/null 2>&1 && \
  167.              echo ${PERSISTENCE_ENCRYPTION} | grep -qve "\<luks\>" ) || \
  168.  
  169.            ( ! is_luks_partition ${dev} >/dev/null 2>&1 && \
  170.              echo ${PERSISTENCE_ENCRYPTION} | grep -qve "\<none\>" )
  171.         then
  172.             continue
  173.         fi
  174.         local result="$(probe_for_gpt_name "${labels}" ${dev})"
  175.         if [ -n "${result}" ]
  176.         then
  177.             echo ${result#*=}
  178.         fi
  179.     done
  180.  
  181.     exit 0
  182. }
  183.  
  184. activate_volumes ()
  185. {
  186.     local volumes=${@}
  187.     local ret=0
  188.     local open_volumes=""
  189.     local successes=""
  190.     local failures=""
  191.  
  192.     # required by open_luks_device()
  193.     exec 6>&1
  194.  
  195.     for vol in ${volumes}
  196.     do
  197.         if [ ! -b "${vol}" ]
  198.         then
  199.             warning "${vol} is not a block device"
  200.             failures="${failures} ${vol}"
  201.             ret=1
  202.             continue
  203.         fi
  204.         if [ -n "$(what_is_mounted_on ${dev})" ]
  205.         then
  206.             warning "${vol} is already mounted"
  207.             failures="${failures} ${vol}"
  208.             ret=1
  209.             continue
  210.         fi
  211.         local luks_vol=""
  212.         if /sbin/cryptsetup isLuks ${vol} >/dev/null 2>&1 
  213.         then
  214.             if luks_vol=$(open_luks_device "${vol}")
  215.             then
  216.                 open_volumes="${open_volumes} ${luks_vol}"
  217.             else
  218.                 failures="${failures} ${vol}"
  219.             fi
  220.         else
  221.             open_volumes="${open_volumes} ${vol}"
  222.         fi
  223.     done
  224.  
  225.     custom_mounts="$(mktemp /tmp/custom_mounts-XXXXXX.list)"
  226.     get_custom_mounts ${custom_mounts} ${open_volumes}
  227.     if [ -s "${custom_mounts}" ]
  228.     then
  229.         activate_custom_mounts ${custom_mounts} &> /dev/null
  230.         fix_gconf_dirs
  231.     fi
  232.     rm -f ${custom_mounts} 2> /dev/null
  233.  
  234.     for vol in ${open_volumes}
  235.     do
  236.         if grep -qe "^${vol}\>" /proc/mounts
  237.         then
  238.             successes="${successes} ${vol}"
  239.         else
  240.             failures="${failures} ${vol}"
  241.             ret=1
  242.         fi
  243.     done
  244.  
  245.     if [ -n "${successes}" ]
  246.     then
  247.         echo "Successes:"
  248.         for vol in ${successes}
  249.         do
  250.             echo "  - ${vol}"
  251.         done
  252.     fi
  253.  
  254.     if [ -n "${failures}" ]
  255.     then
  256.         echo "Failures:"
  257.         for vol in ${failures}
  258.         do
  259.             echo "  - ${vol}"
  260.         done
  261.     fi
  262.     exit ${ret}
  263. }
  264.  
  265. close_volumes ()
  266. {
  267.     local volumes=${@}
  268.     local custom_mounts="$(mktemp /tmp/custom_mounts-XXXXXX.list)"
  269.     get_custom_mounts ${custom_mounts} ${volumes}
  270.     while read device source dest options # < ${custom_mounts}
  271.     do
  272.         if [ "${options}" != linkfiles ]
  273.         then
  274.             umount ${dest} 2> /dev/null
  275.         fi
  276.     done < ${custom_mounts}
  277.     rm -f ${custom_mounts} 2> /dev/null
  278.     for vol in ${volumes}
  279.     do
  280.         local backing=$(where_is_mounted ${vol})
  281.         umount ${backing}
  282.     done
  283. }
  284.  
  285. main ()
  286. {
  287.     # tracing get's activated by Arguments() if "debug" is in /proc/cmdline
  288.     # which may be something we don't want to flood stderr
  289.     exec 3<>"/dev/null"
  290.     BASH_XTRACEFD="3"
  291.  
  292.     # parse the kernel cmdline for live-boot's configuration as defaults
  293.     Cmdline
  294.  
  295.     # note that this is not enough for disabling tracing. we need to do the
  296.     # $BASH_XTRACEFD stuff above to avoid tracing until this point.
  297.     set +x
  298.  
  299.     export PERSISTENCE="true"
  300.     export NOPERSISTENCE=""
  301.  
  302.     # Should be set empty since live-boot already changed root for us
  303.     export rootmnt=""
  304.  
  305.     while echo "${1}" | grep -qe "^--[^ ]\+\>"
  306.     do
  307.         case "${1}" in
  308.             --encryption=*)
  309.                 export PERSISTENCE_ENCRYPTION="${1#*=}"
  310.                 ;;
  311.             --help)
  312.                 usage
  313.                 exit 0
  314.                 ;;
  315.             --log-file=*)
  316.                 local log_file="${1#*=}"
  317.                 [ -e "${log_file}" ] && rm -f "${log_file}"
  318.                 exec 3<>"${log_file}"
  319.                 set -x
  320.                 ;;
  321.             --media=*)
  322.                 export PERSISTENCE_MEDIA="${1#*=}"
  323.                 ;;
  324.             --read-only)
  325.                 export PERSISTENCE_READONLY="true"
  326.                 ;;
  327.             --read-write)
  328.                 export PERSISTENCE_READONLY=""
  329.                 ;;
  330.             --union=*)
  331.                 export UNIONTYPE="${1#*=}"
  332.                 ;;
  333.             *)
  334.                 error "unrecognized option: ${1}"
  335.                 ;;
  336.         esac
  337.         shift
  338.     done
  339.  
  340.     local action="${1}"
  341.     shift
  342.     case "${action}" in
  343.         list)
  344.             local labels=${@}
  345.             if ! echo ${labels} | grep -qe "[^[:space:]]"
  346.             then
  347.                 # use default from live-helpers
  348.                 labels=${custom_overlay_label}
  349.             fi
  350.             list_gpt_volumes ${labels}
  351.             ;;
  352.         activate|close)
  353.             if ! echo ${@} | grep -qe "[^[:space:]]"
  354.             then
  355.                 error "you must specify at least one volume"
  356.             fi
  357.             ${action}_volumes "${@}"
  358.             ;;
  359.         "")
  360.             error "no action specified"
  361.             ;;
  362.         *)
  363.             error "unrecognized action: ${action}"
  364.             ;;
  365.     esac
  366. }
  367.  
  368. main ${@}
  369.